﻿/**
 * Created by xjchen on 2020-03-19.
 * */

#ifndef MIDDLEWARE_ETHERNETREADER_H
#define MIDDLEWARE_ETHERNETREADER_H


#include "DeviceReader.h"
#include "AutoDetectReader.h"
#include "Wrapper.h"
#include "Function.h"
#include <string>
#include <vector>
#include <map>

typedef enum TransportProtocol {
    TCP,
    UDP
} TransportProtocol;

class TCPServer;

class UDPServer;

class EthernetReader : public DeviceReader {
public:
    EthernetReader(TransportProtocol protocol, uint16_t port);

    ~EthernetReader();

    int64_t onRead(char *buffer, int64_t len) override;

    uint16_t getPort();

    /**
     * 返回socket描述符，一般在 setPostSetupAction() 中使用
     * 
     * @return SOCKET, 无效时返回INVALID_SOCKET
     */
    SOCKET getSocket();

    void setOwner(AutoDetectReader *reader);

    void setupConnection() override;

    /**
     * 设置 setupConnection() 完成后动作
     * 
     * 传入的函数应同时在 AppDelegate::onConfigure() 中使用 REGISTER_FUNCTIONS() 进行注册
     */
    FLOW_API void setPostSetupAction(void (*func)(EthernetReader *));

    void stop() override;

    /**
     * 加入组播组
     * 
     * @param addr 要加入的组播组地址
     * @param intf 监听的接口IP地址，默认为所有接口
     * 
     * @return 
     *       0: 成功
     *      -1: 失败
     */
    FLOW_API int joinMulticastGroup(const std::string addr, const std::string intf = "");

    /**
     * 离开组播组
     * 
     * @param addr 要离开的组播组地址
     * @param intf 监听的接口IP地址，默认为所有接口
     * 
     * @return 
     *       0: 成功
     *      -1: 失败
     */
    int leaveMulticastGroup(const std::string addr, const std::string intf = "");

private:
    TCPServer *tcpServer = nullptr;
    UDPServer *udpServer = nullptr;
    std::vector<std::pair<std::string, std::string>> mcGroups;
    Function postSetupAction;
    AutoDetectReader *owner = nullptr;
};


#endif /** MIDDLEWARE_ETHERNETREADER_H */
